package com.zijidelu.luframework.base.bizsig;

import cn.hutool.core.lang.func.Func1;
import com.zijidelu.luframework.base.model.DataModel;

import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Supplier;

/**
 * 业务签名缓存管理器。
 * <p>
 * 负责为每个 BizSignature 实例提供和管理其元数据缓存。
 *
 * @author ZIJIDELU
 * @datetime 2025/4/17 23:27
 */
final class BizSignatureCacheManager { // 改为 final 和包私有

    private static final Map<BizSignature<?>, BizSignatureRecord<?>> CACHE = new ConcurrentHashMap<>();

    @SuppressWarnings("unchecked")
    public static <D extends DataModel> BizSignatureRecord<D> getBizSignatureRecord(BizSignature<D> bizSignature) {
        return (BizSignatureRecord<D>) CACHE.computeIfAbsent(bizSignature, k -> new BizSignatureRecord<>());
    }

    /**
     * 业务签名缓存类。
     * <p>
     * 该类负责管理业务签名的各种元数据缓存，并确保线程安全的延迟初始化。
     */
    static final class BizSignatureRecord<D extends DataModel> {

        // 使用 volatile 保证多线程下的可见性
        private volatile List<FieldDescriptor<D>> fieldDescriptorList;
        private volatile List<Func1<D, ?>> bizSigFieldList;
        private volatile List<String> bizSigFieldNameList;
        private volatile Map<Func1<D, ?>, FieldDescriptor<D>> bizSignatureFieldMap;
        private volatile Map<String, FieldDescriptor<D>> bizSignatureFieldNameMap;

        /**
         * 获取或计算字段描述符列表。
         * 使用双重检查锁定模式，确保线程安全且高效。
         */
        public List<FieldDescriptor<D>> getFieldDescriptorList(Supplier<List<FieldDescriptor<D>>> supplier) {
            if (fieldDescriptorList == null) { // 第一次检查（无锁）
                synchronized (this) {
                    if (fieldDescriptorList == null) { // 第二次检查（加锁）
                        fieldDescriptorList = List.copyOf(supplier.get()); // 创建不可变副本
                    }
                }
            }
            return fieldDescriptorList;
        }

        public List<Func1<D, ?>> getBizSigFieldList(Supplier<List<Func1<D, ?>>> supplier) {
            if (bizSigFieldList == null) {
                synchronized (this) {
                    if (bizSigFieldList == null) {
                        bizSigFieldList = List.copyOf(supplier.get());
                    }
                }
            }
            return bizSigFieldList;
        }

        public List<String> getBizSigFieldNameList(Supplier<List<String>> supplier) {
            if (bizSigFieldNameList == null) {
                synchronized (this) {
                    if (bizSigFieldNameList == null) {
                        bizSigFieldNameList = List.copyOf(supplier.get());
                    }
                }
            }
            return bizSigFieldNameList;
        }

        public Map<Func1<D, ?>, FieldDescriptor<D>> getBizSignatureFieldMap(Supplier<Map<Func1<D, ?>, FieldDescriptor<D>>> supplier) {
            if (bizSignatureFieldMap == null) {
                synchronized (this) {
                    if (bizSignatureFieldMap == null) {
                        bizSignatureFieldMap = Map.copyOf(supplier.get());
                    }
                }
            }
            return bizSignatureFieldMap;
        }

        public Map<String, FieldDescriptor<D>> getBizSignatureFieldNameMap(Supplier<Map<String, FieldDescriptor<D>>> supplier) {
            if (bizSignatureFieldNameMap == null) {
                synchronized (this) {
                    if (bizSignatureFieldNameMap == null) {
                        bizSignatureFieldNameMap = Map.copyOf(supplier.get());
                    }
                }
            }
            return bizSignatureFieldNameMap;
        }
    }

}
